#include "contact.h"
/*
    参数： 用户信息
    功能：  向进程B获取用户的联系人列表
    返回值：成功：联系人列表空间地址，失败: NULL
*/
PSeqListType InitContactTable(PUserType pUser)
{
    if(pUser == NULL)
    {
        return NULL;
    }

    PSeqListType pContactList = CreateEpSeqlist();

    //检查创建是否成功
	if (pContactList == NULL) {
		return NULL;
	}

    //向进程B获取联系人列表
    RequsetGetContactList(pUser, pContactList);
    return pContactList;
}

//联系人资源释放
void ContactFree(PSeqListType* pContactList)
{
    MyFree(pContactList);
}

/*
	功能：向通讯录中添加联系人
	参数：
        pUser           用户信息空间地址
        pContactList	通讯录在内存中的地址,非空NULL
		data	        添加的联系人
	返回值：添加是否成功，成功返回0，失败返回-1
*/
int InsertIntoContacts(PUserType pUser, PSeqListType pContactList, PElementType pData)
{
    if(pUser == NULL || pContactList == NULL)
    {
        return -1;
    }

    int res = -1;
    // 添加联系人:	
    res = RequestAddContact(pData);
    if(res == -1)//添加失败则
    {
        PrintWran("添加失败!\n");
        return -1;
    }

    res = InsertIntoSeqlist(pContactList, 0, *pData);
    if(res == -1)//添加异常
    {
        PrintWran("添加异常!\n");
        return -1;
    }
    else//添加成功
    {
        //PrintWran("添加成功!\n");
        return 0;
    }
}

// 查询联系人存在信息
// 参数： userId 联系人电话
// 功能：查询联系人
// 返回值：存在 联系人ID, 不存在 -1
int IsContactExistByPhone(PSeqListType pContactList, lType userId)
{
    if(pContactList == NULL || pContactList->last == -1)
        return -1;
    
    int post = -1;
    for(int i = 0; i <= pContactList->last; i++)
    {
        if(pContactList->data[i].contactInfo.contactId == userId)
        {
            return i;
        }
    }
    return post;
}

/*
	参数：
		pContactList	通讯录在内存中的地址,非空NULL
		name 			联系人姓名
	功能：根据姓名在通信录中显示联系人
*/
void ShowContactByName(PSeqListType pContactList, const char*name)
{
    if(pContactList == NULL || pContactList->last == -1)
    {
        // 提示没有此联系人
        PrintWran("没有此联系人！\n");
        return ;
    }
    int post = -1;
    for(int i = 0; i <= pContactList->last; i++)
    {
        if(strcmp(pContactList->data[i].contactInfo.name, name) == 0)
        {
            if(post == -1)
            {
                char buf[100] = "";
                sprintf(buf, "联系人姓名%-2c  联系电话%-2c 性别%-1c   年龄  家庭住址\n", 0, 0, 0);
                PrintCenter(buf);
            }
            ShowContactInfo(0, pContactList->data[i].contactInfo);
            post = i;
        }
    }
    
    if(post == -1)// 查找失败则
    {
        // 提示没有此联系人
        PrintWran("没有此联系人！\n");
    }

}
    
/*
	功能：在通讯录中删除联系人
	参数：
        pContactList		通讯录空间地址
        pContact           联系人信息空间地址
	返回值：删除是否成功，成功返回0，失败返回-1
*/
int DeleteContacts(PSeqListType pContactList, PContactType pContact)
{
    if(pContactList == NULL || pContact == NULL)
    {
        return -1;
    }

    int res = -1;
    // 1）发送删除联系人信息请求
    res = RequestDeleteContact(pContact);
    if(res == -1)//添加失败则
    {
        PrintWran("删除失败!\n");
        return -1;
    }    
    
    // 2）删除通信录表中的联系人
    int post = IsContactExistByPhone(pContactList, pContact->contactId);
    res = DeletePostSeqlist(pContactList, post);
    if(res == -1)//删除异常
    {
        PrintWran("删除异常!\n");
        return -1;
    }
    else//删除成功
    {
        PrintWran("删除成功!\n");
        return 0;
    }
}

/*
	参数：
		pContactList	通讯录在内存中的地址,非空NULL
		name 			联系人姓名
	功能：根据姓名在通信录中查找联系人
	返回值：联系人下标
*/
int IsContactExistByName(PSeqListType pContactList, const char *name)
{
    if(pContactList == NULL || pContactList->last == -1)
        return -1;

    int post = -1;
    for(int i = 0; i <= pContactList->last; i++)
    {
        if(strcmp(pContactList->data[i].contactInfo.name, name) == 0)
        {
            return i;
        }
    }
    return post;
}

/*
	功能：向通讯录中修改联系人
	参数：pContact	通讯录在内存中的地址,非空NULL
		 data	   修改的联系人
	返回值：修改是否成功，成功返回0，失败返回-1
*/
int ModifyContacts(PSeqListType pContactList, PElementType pData)
{
    if(pContactList == NULL || pContactList->last == -1)
    {
        return -1;
    }

    int res = -1;
    // 1）发送修改联系人信息请求	
    res = RequestChangeContact(&pData->contactInfo);
    if(res == -1)//修改失败则
    {
        PrintWran("修改失败!\n");
        return -1;
    }    
    
    
    int post = IsContactExistByPhone(pContactList, pData->contactInfo.contactId); 
    res = ChangePostSeqList(pContactList, post, *pData);
    if(res == -1)//修改异常
    {
        PrintWran("修改异常!\n");
        return -1;
    }
    else//修改成功
    {
        PrintWran("修改成功!\n");
        return 0;
    }
}

/*
	功能：在通讯录中清空联系人
	参数：
        pUser           用户信息空间地址
        pContactList	通讯录在内存中的地址,非空NULL
	返回值：
        -1 程序异常
        0  清空成功
*/
int ClearContact(PUserType pUser, PSeqListType pContactList)
{
    if(pUser == NULL || pContactList == NULL || pContactList->last == -1)
    {
        // 提示没有此联系人
        PrintWran("通信录中没有联系人了！\n");
        return -1;
    }
    int res = -1;
    // 1）发送清空联系人信息请求
    res = RequestClearContact(pUser);
    if(res == -1)// 清空失败则
    {
        PrintWran("清空失败！\n");//提示清空失败
        return -1;
    }    

    //2）清空通信录表
    ClearSeqList(pContactList);

    PrintWran("清空成功！\n");
    return 0;
}

/*                    Server                      */
/*
    pContactTable 联系人信息表空间地址
    功能：将联系人信息表保存到文件中
*/
void SaveContactTable(PSeqListType pContactTable)
{
    if(pContactTable == NULL)
    {
        return ;
    }
    char path[50] = "./ContactTable";
    int fd = -1;
    int res = -1;

    //从文件中以二进制方式读出保存到用户信息表
    fd = open(path, O_WRONLY|O_CREAT|O_TRUNC,0666);
	if(-1 == fd)
	{
		return ;
	}
	
    for(int i = 0; i <= pContactTable->last; i++)
    {
        res = write(fd, &pContactTable->data[i],sizeof(pContactTable->data[i]));
        if(res == -1)
        {
            return ;
        }
    }
	close(fd);
}

/*
    功能：从文件中载入联系人信息表
    返回值：成功：联系人信息表空间地址，失败: NULL
*/
PSeqListType LoadContactTable()
{
    char path[50] = "./ContactTable";
    ElementType contact = {};
    int fd = -1;
    int res = -1;

    PSeqListType pContactTable = CreateEpSeqlist();//注意内存泄漏！
	//检查开辟空间是否成功
	if (pContactTable == NULL) {
		return NULL;
	}

    //从文件中以二进制方式读出保存到用户信息表
    fd = open(path,  O_RDONLY|O_CREAT,0666);
	if(-1 == fd)
	{
        MyFree(&pContactTable);
		return NULL;
	}
	
    while(1)
    {
        res = read(fd, &contact, sizeof(contact));//res 0, -1, 个数
        if(res == -1)
        {
            MyFree(&pContactTable);
            return NULL;
        }
        else if(res == 0)
        {
            break;//读完了
        }
        else
        {
            //保存到用户信息表
            InsertIntoSeqlist(pContactTable, pContactTable->last + 1, contact);
        }
    }
	close(fd);
    return pContactTable;
}

//根据userPhone, contactPhone查找联系下标
//查找失败 -1  成功 下标
int SelectContactByUserIdAndContactId(const PSeqListType pContactTable, long userId, long contactId)
{
    for(int i = 0; i <= pContactTable->last; i++)
    {
        if(pContactTable->data[i].contactInfo.userId == userId)
        {
            if(pContactTable->data[i].contactInfo.contactId == contactId)
            {
                return i;
            }
        }
    }
    return -1;
}

// 获取该用户所有存在的联系人返回进程A
void GetContactList(long userId, const PSeqListType pContactTable)
{
    // 获取该用户所有存在的联系人到通信录表（在数组中查询）
    PSeqListType pContactList = CreateEpSeqlist();
    if(pContactList == NULL)
    {
        //返回通信录表
        ResponseGetContactList(userId, NULL);
        return;
    }

    for(int i = 0; i <= pContactTable->last; i++)
    {
        //跟据用户电话查找这个用户的所有联系人，并判断表中是否存在
        if(pContactTable->data[i].contactInfo.userId == userId)
        {
            ElementType data = {};
            data.contactInfo = pContactTable->data[i].contactInfo;
            int res = InsertIntoSeqlist(pContactList, pContactList->last + 1, data);
            if(res == -1)
            {
                //返回通信录表
                ResponseGetContactList(userId, NULL);
                MyFree(&pContactList);
                return;
            }
        }
    }

    //返回通信录表
    ResponseGetContactList(userId, pContactList);
    MyFree(&pContactList);
}

// 添加联系人信息（向数组中添加信息）
// 添加成功 0 ，添加失败 -1
int AddContact(long userId, PSeqListType pContactTable, PContactType pData)
{
    ElementType data = {};
    data.contactInfo = *pData;
    int result = -1;
    int last = pContactTable->last;
   
    result = InsertIntoSeqlist(pContactTable, pContactTable->last + 1, data);
    if(result == -1)//添加失败
    {
        result = -1;
        ResponseAddContact(userId, -1);
    }
    else
    {
        result = 0;
        ResponseAddContact(userId, 0);
    }
    return result;
}

// 删除联系人信息（向数组中添加信息）
// 删除成功 0 ，删除异常 -1 删除失败 1
int DeleteContact(PSeqListType pContactTable, PContactType pData)
{
    int post = SelectContactByUserIdAndContactId(pContactTable, pData->userId, pData->contactId);
    if(post != -1)
    {
        int res = DeletePostSeqlist(pContactTable, post);
        if(res == 1)
        {
            ResponseDeleteContact(pData->userId, 0);
            return 0;
        }
        else
        {
            ResponseDeleteContact(pData->userId, -1);
            return -1;
        }
    }
    else
    {
        ResponseDeleteContact(pData->userId, -1);
        return 1;
    }
}

// 修改联系人信息
// -1 程序异常
// 0  修改成功
// 1  修改失败
int ChangeContact(PSeqListType pContactTable, PContactType pData)
{
    ElementType data = {};
    data.contactInfo = *pData;

    int post = SelectContactByUserIdAndContactId(pContactTable, pData->userId, pData->contactId);
    if(post != -1)
    {
        int res = ChangePostSeqList(pContactTable, post, data);
        if(res == 1)
        {
            ResponseChangeContact(pData->userId, 0);
            return 0;
        }
        else
        {
            ResponseChangeContact(pData->userId, -1);
            return -1;
        }
    }
    else
    {
        ResponseChangeContact(pData->userId, -1);
        return 1;
    }
}

/*
	功能：清空联系人
	参数：
        pContactTable	联系人表信息的地址,非空NULL
        pUser           用户信息空间地址
	返回值：
        -1 程序异常
        0  清空成功
*/
int CleanContact(PSeqListType pContactTable , PUserType pUser)
{
    for(int i = 0; i <= pContactTable->last; i++)
    {
        if(pContactTable->data[i].contactInfo.userId == pUser->userId)
        {
            int res = DeletePostSeqlist(pContactTable, i);
            if(res == -1)
            {
                ResponseClearContact(pUser->userId, -1);
                return -1;
            }
        }
    }
    ResponseClearContact(pUser->userId, 0);
    return 0;
}